const { RegexActionParser } = require('../out/utils/regexActionParser');
const fs = require('fs');
const path = require('path');

/**
 * Test edge cases for action extraction
 */
function testEdgeCases() {
    console.log('=== Testing Edge Cases for Action Extraction ===\n');
    
    // Test Case 1: Functions with no parameters
    const testNoParams = `
export default {
  actions: {
    ...baseActions,
    simpleAction() {
      return 'no params';
    },
    asyncNoParams: async function() {
      return await Promise.resolve();
    },
    arrowNoParams: () => {
      console.log('arrow function');
    }
  }
};
`;
    
    // Test Case 2: C++ bracket alignment style
    const testCppStyle = `
export default {
  actions: 
  {
    ...baseActions,
    cppStyleAction()
    {
      return 'cpp style';
    },
    asyncCppStyle: async function()
    {
      return await api.getData();
    },
    normalAction: function()
    {
      console.log('normal function');
    }
  }
};
`;
    
    // Test Case 3: Multiple line breaks before actions
    const testMultipleBreaks = `
export default {
  actions: {
    ...baseActions,


    actionWithBreaks() {
      return 'after breaks';
    },



    anotherAction: function() {
      return 'more breaks';
    },




    thirdAction: async () => {
      return 'lots of breaks';
    }
  }
};
`;
    
    // Test Case 4: Multiple comments before actions
    const testMultipleComments = `
export default {
  actions: {
    ...baseActions,
    // This is a comment
    // Another comment line
    /* Multi-line comment
       with multiple lines */
    commentedAction() {
      return 'after comments';
    },
    
    /**
     * JSDoc style comment
     * @param {Object} context - Vuex context
     * @returns {Promise} - Promise result
     */
    // Single line comment too
    jsdocAction: async function(context) {
      return await api.call();
    },
    
    /*
    * Block comment style
    * Multiple lines here
    */
    blockCommentAction: () => {
      console.log('after block comment');
    }
  }
};
`;
    
    // Test Case 5: Root store with same issues
    const testRootStore = `
import { createStore } from 'vuex';

const store = createStore({
  state: {
    loading: false
  },
  actions: 
  {
    ...baseActions,
    
    
    // Comment before action
    /* Another comment */
    rootNoParams()
    {
      console.log('root no params');
    },



    /**
     * JSDoc comment
     */
    rootWithComments: async function()
    {
      return 'root with comments';
    }
  }
});

export default store;
`;
    
    const testCases = [
        {
            name: 'No Parameters Functions',
            content: testNoParams,
            expectedActions: ['simpleAction', 'asyncNoParams', 'arrowNoParams'],
            isModule: true
        },
        {
            name: 'C++ Bracket Style',
            content: testCppStyle,
            expectedActions: ['cppStyleAction', 'asyncCppStyle', 'normalAction'],
            isModule: true
        },
        {
            name: 'Multiple Line Breaks',
            content: testMultipleBreaks,
            expectedActions: ['actionWithBreaks', 'anotherAction', 'thirdAction'],
            isModule: true
        },
        {
            name: 'Multiple Comments',
            content: testMultipleComments,
            expectedActions: ['commentedAction', 'jsdocAction', 'blockCommentAction'],
            isModule: true
        },
        {
            name: 'Root Store Edge Cases',
            content: testRootStore,
            expectedActions: ['rootNoParams', 'rootWithComments'],
            isModule: false
        }
    ];
    
    const results = [];
    
    testCases.forEach((testCase, index) => {
        console.log(`\n--- Test Case ${index + 1}: ${testCase.name} ---`);
        
        const testFilePath = path.join(__dirname, `test-edge-case-${index + 1}.js`);
        
        try {
            // Write test file
            fs.writeFileSync(testFilePath, testCase.content);
            
            // Extract actions
            const startTime = Date.now();
            let actionNames;
            if (testCase.isModule) {
                actionNames = RegexActionParser.getModuleActionNames(testFilePath, 'testModule');
            } else {
                actionNames = RegexActionParser.getRootActionNames(testFilePath);
            }
            const endTime = Date.now();
            
            console.log(`Extraction completed in ${endTime - startTime}ms`);
            console.log(`Found ${actionNames.length} total actions:`);
            actionNames.forEach((action, i) => {
                console.log(`  ${i + 1}. ${action}`);
            });
            
            // Check expected actions
            const foundExpected = testCase.expectedActions.filter(expected => {
                const fullActionName = testCase.isModule ? `testModule/${expected}` : expected;
                return actionNames.includes(fullActionName);
            });
            
            const missing = testCase.expectedActions.filter(expected => {
                const fullActionName = testCase.isModule ? `testModule/${expected}` : expected;
                return !actionNames.includes(fullActionName);
            });
            
            console.log(`\n✓ Found ${foundExpected.length}/${testCase.expectedActions.length} expected actions:`);
            foundExpected.forEach(action => {
                const fullName = testCase.isModule ? `testModule/${action}` : action;
                console.log(`  ✓ ${fullName}`);
            });
            
            if (missing.length > 0) {
                console.log(`\n✗ Missing expected actions:`);
                missing.forEach(action => {
                    const fullName = testCase.isModule ? `testModule/${action}` : action;
                    console.log(`  ✗ ${fullName}`);
                });
            }
            
            const success = missing.length === 0;
            results.push({
                name: testCase.name,
                success,
                found: foundExpected.length,
                expected: testCase.expectedActions.length,
                missing: missing
            });
            
            // Clean up
            fs.unlinkSync(testFilePath);
            
        } catch (error) {
            console.error(`Error in test case: ${error.message}`);
            results.push({
                name: testCase.name,
                success: false,
                error: error.message
            });
            
            // Clean up on error
            if (fs.existsSync(testFilePath)) {
                fs.unlinkSync(testFilePath);
            }
        }
    });
    
    return results;
}

/**
 * Analyze test results and provide recommendations
 */
function analyzeResults(results) {
    console.log('\n=== Test Results Analysis ===\n');
    
    const totalTests = results.length;
    const passedTests = results.filter(r => r.success).length;
    const failedTests = results.filter(r => !r.success);
    
    console.log(`📊 Overall Results: ${passedTests}/${totalTests} tests passed (${((passedTests/totalTests) * 100).toFixed(1)}%)`);
    
    if (passedTests === totalTests) {
        console.log('🎉 All edge case tests passed! The functions handle all tested scenarios correctly.');
    } else {
        console.log('\n❌ Failed Tests:');
        failedTests.forEach((result, index) => {
            console.log(`\n${index + 1}. ${result.name}`);
            if (result.error) {
                console.log(`   Error: ${result.error}`);
            } else if (result.missing) {
                console.log(`   Missing actions: ${result.missing.join(', ')}`);
                console.log(`   Found: ${result.found}/${result.expected}`);
            }
        });
        
        console.log('\n🔧 Recommendations for fixes:');
        
        // Analyze specific failure patterns
        const hasNoParamIssues = failedTests.some(r => r.name.includes('No Parameters'));
        const hasCppStyleIssues = failedTests.some(r => r.name.includes('C++ Bracket'));
        const hasLineBreakIssues = failedTests.some(r => r.name.includes('Line Breaks'));
        const hasCommentIssues = failedTests.some(r => r.name.includes('Comments'));
        
        if (hasNoParamIssues) {
            console.log('1. 🔧 No Parameters: Improve regex to handle functions without parameters');
        }
        if (hasCppStyleIssues) {
            console.log('2. 🔧 C++ Style: Enhance brace matching to handle different bracket styles');
        }
        if (hasLineBreakIssues) {
            console.log('3. 🔧 Line Breaks: Improve whitespace normalization to handle multiple line breaks');
        }
        if (hasCommentIssues) {
            console.log('4. 🔧 Comments: Enhance comment removal to handle all comment styles');
        }
    }
    
    return {
        totalTests,
        passedTests,
        failedTests: failedTests.length,
        success: passedTests === totalTests
    };
}

// Run tests
console.log('Testing Edge Cases for getModuleActionNames and getRootActionNames');
console.log('================================================================\n');

const testResults = testEdgeCases();
const analysis = analyzeResults(testResults);

console.log('\n=== Edge Case Testing Summary ===');
console.log(`✅ Functions tested: getModuleActionNames, getRootActionNames`);
console.log(`✅ Edge cases covered: No params, C++ style, line breaks, comments`);
console.log(`✅ Test scenarios: ${analysis.totalTests}`);
console.log(`${analysis.success ? '🎉' : '⚠️'} Success rate: ${analysis.passedTests}/${analysis.totalTests}`);

if (!analysis.success) {
    console.log('\n⚠️  Some edge cases need attention. Review the analysis above for specific fixes needed.');
} else {
    console.log('\n🎉 All edge cases pass! The functions are robust and handle various coding styles correctly.');
}

module.exports = { testEdgeCases, analyzeResults };